<!--
 * @Author: mayijun
 * @Date: 2022-06-15 10:52:40
 * @LastEditors: mayijun
 * @LastEditTime: 2022-08-09 17:59:08
-->
<script lang="ts" setup>
import {
  IconCaretDown,
  IconCaretUp,
  IconInfoCircle
} from '@arco-design/web-vue/es/icon';
import { computed, onMounted, PropType, reactive, ref, watch } from 'vue';
import ModelDataResult from '../modelDataResult/index.vue';
import StatPeriod from '../statPeriod/index.vue';
import BusinessLine from '../businessLine/index.vue';
import API from '@/services';
import { store } from '@/store';
import { useRoute, useRouter } from 'vue-router';
import _ from 'lodash';
import { IBusinessLimit } from '@/constants/indexDevelop';
import { Message } from '@arco-design/web-vue';
import Bus from '@/utils/emmit';

const route = useRoute();
const router = useRouter();
//上线状态
let status = ref<any>(route.query.status);

const props = defineProps({
  deriveDetailData: {
    type: Object as PropType<defs.DeriveModelDto>,
    default: () => {}
  }
});

// 是否展示预览结果
const isShowPreview = ref<Boolean>(false);

// 预览的表视角数据
const previewData: any = ref(null);

// 预览指标视角数据
const indexViewData: any = ref(null);

//数据预览提交结构
const deriveModel = ref<defs.DeriveModelDto>({});
//统计周期对象
const countCycle = ref<defs.CountCycleDto>({});
//业务范围对象
const businessLimit = ref<IBusinessLimit>({
  countTypeDto: {
    begin: 0,
    countType: 0,
    countWay: '',
    end: 0,
    filterValue: ''
  } as defs.CountTypeDto,
  tableFieldColumn: '',
  tableFieldName: '',
  type: 'and',
  isRoot: true,
  compontType: 2,
  children: []
});
//最大层级
const treeMax = ref({ num: 1 });

const state = reactive({
  developType: '1', //开发方式
  resizeHeight: 0 as any, //数据结果拖拽高度
  modelValue: '' as any, //数据模型选择值
  curModel: {} as any, //选中当前模型对象
  modelOptions: [] as any[], //模型列表
  modelTableColumnList: [] as any[], //模型字段列表
  dimensionList: [] as any[], //可用维度列表
  dimensionIdList: [] as any[], //可用维度已选
  isStatPeriodSelect: false, //控制统计周期添加状态
  isBusinessLineSelect: false //控制业务范围添加状态
});
//表格参数
let formParams = reactive({
  pageNum: 1,
  pageSize: 10,
  status: 0,
  type: 0 // 0 表视角；1指标视角
});

// 获取原子指标的中文文名称
const indexCnName = computed(() => {
  return store.state.metricsdevelop.metricsCnName;
});

// 查询模型下拉框
const getModelList = async (id: number) => {
  const { code, data } = await API.dataModel.getGetDeriveModelListById({ id });
  if (code === 200 && Array.isArray(data)) {
    if (data.length > 0) {
      data.map((item: any) => {
        item.label = item.modelName;
        item.value = item.id;
      });
      state.modelOptions = data;
      //默认选择第一个
      state.modelValue = state.modelOptions[0].value;
      state.curModel = state.modelOptions[0];
      //时间频度
      deriveModel.value.timeframe = state.curModel.countDateType;
      //默认查询模型字段列表
      getModelTableColumn(state.modelValue);
    }
  }
};

//模型切换的方法
const modelChange = () => {
  //清空之前的配置数据
  isShowPreview.value = false;
  previewData.value = null;
  indexViewData.value = null;
  deriveModel.value = {};
  countCycle.value = {};
  businessLimit.value = {
    countTypeDto: {
      begin: 0,
      countType: 0,
      countWay: '',
      end: 0,
      filterValue: ''
    } as defs.CountTypeDto,
    tableFieldColumn: '',
    tableFieldName: '',
    type: 'and',
    isRoot: true,
    compontType: 2,
    children: []
  };
  treeMax.value.num = 1;
  formParams.pageNum = 1;
  formParams.pageSize = 10;
  formParams.status = 0;
  formParams.type = 0;
  state.resizeHeight = 0;
  state.isStatPeriodSelect = false;
  state.isBusinessLineSelect = false;

  //模型字段
  state.curModel = state.modelOptions.find(
    (item) => item.value == state.modelValue
  );
  //时间频度
  deriveModel.value.timeframe = state.curModel.countDateType;
  getModelTableColumn(state.modelValue);
};

//查询模型下字段列表
const getModelTableColumn = async (modelId: any, columnName?: any) => {
  const { code, data } = await API.dataModel.postGetModelTableColumn({
    columnName: columnName,
    modelId: modelId
  });
  if (code === 200 && Array.isArray(data)) {
    //业务范围
    state.modelTableColumnList = _.cloneDeep(data);
    //下拉框结构
    state.modelTableColumnList.map((item: any) => {
      item.value = item.tableFieldName + item.tableName;
      item.label = item.tableFieldDesc;
    });
    //业务范围选择，去掉日期类型
    state.modelTableColumnList = state.modelTableColumnList.filter(
      (item: any) => item.tableFieldType != 'DATETIME'
    );
    //可用维度列表
    state.dimensionList = _.cloneDeep(data);
    //下拉框结构
    state.dimensionList.map((item: any) => {
      item.value = item.dimensionId;
      item.label = item.dimensionName;
    });
    state.dimensionList = state.dimensionList.filter(
      (item: any) => item.ifBindDimension === 1
    );
    if (!route.query.id) {
      //可用维度列表默认全部选中
      state.dimensionIdList = state.dimensionList.map(
        (item: any) => item.dimensionId
      );
    }
  }
};

// 数据结果切换分页
const changePageNum = (v: any, type: any) => {
  let { pageNum, pageSize } = v;
  formParams.pageNum = pageNum;
  formParams.pageSize = pageSize;
  handlePreviewData(type);
};

// 数据结果切换分页
const changePageSize = (v: any, type: any) => {
  let { pageNum, pageSize } = v;
  formParams.pageNum = pageNum;
  formParams.pageSize = pageSize;
  handlePreviewData(type);
};

// 数据结果切换tab
const changeTableTab = (v: any) => {
  handlePreviewData(Number(v));
};

/**
 * @description 预览
 * @tabType  0：表视角；1：指标视角
 * @status 0:草稿；1：上线；2：下线
 */
const handlePreviewData = async (tabType: any) => {
  //必须要填一个
  if (
    (!state.isStatPeriodSelect ||
      (state.isStatPeriodSelect && !countCycle.value.type)) &&
    (!state.isBusinessLineSelect ||
      (state.isBusinessLineSelect &&
        businessLimit.value.children &&
        businessLimit.value.children[0].countTypeDto?.countWay != "IS_NULL" &&
        businessLimit.value.children[0].countTypeDto?.countWay != "IS_NOT_NULL" &&
        businessLimit.value.children[0].countTypeDto?.filterValue === ''))
  ) {
    Message.warning('请添加统计周期或者业务范围');
    return false;
  }

  //统计周期
  if (
    state.isStatPeriodSelect &&
    countCycle.value.type == 'customize' &&
    countCycle.value.begin &&
    countCycle.value.end &&
    countCycle.value.begin < countCycle.value.end
  ) {
    Message.warning('统计周期的开始日期要大于日期');
    return false;
  }
  commonParams(tabType);
  //数据预览
  const { code, data } = await API.metricsModelRelation.postGetDeriveModelData(
    deriveModel.value
  );
  if (code === 200) {
    if (tabType === 0) {
      previewData.value = data;
    } else if (tabType === 1) {
      indexViewData.value = data;
    }
    //没有打开，直接打开
    if (!isShowPreview.value) {
      isShowPreview.value = true;
      state.resizeHeight = null;
    }
  }
};
//参数整理
const commonParams = (tabType: any) => {
  //派生指标id
  let metricsId: any = route.query.metricsId;
  let id: any = route.query.id;
  //数据预览派生指标id赋值
  deriveModel.value.id = id;
  deriveModel.value.derivedMetricsId = metricsId;
  deriveModel.value.metricsId = state.curModel.metricsId;
  deriveModel.value.modelId = state.curModel.id;
  //统计周期
  if (state.isStatPeriodSelect) {
    deriveModel.value.countCycleDto = countCycle.value;
  } else {
    deriveModel.value.countCycleDto = null as any;
  }
  deriveModel.value.type = tabType;
  deriveModel.value.status = formParams.status;
  deriveModel.value.pageNum = formParams.pageNum;
  deriveModel.value.pageSize = formParams.pageSize;
  //业务范围处理
  if (state.isBusinessLineSelect) {
    let bs = _.cloneDeep(businessLimit.value);
    businessLimitValue(bs);
    deriveModel.value.limitDto = bs;
  } else {
    deriveModel.value.limitDto = null as any;
  }
  //可用维度
  deriveModel.value.dimList = state.dimensionIdList;
};

//业务范围数据处理
const businessLimitValue = (limit: any) => {
  delete limit.isRoot;
  delete limit.compontType;
  if (limit.countTypeDto && limit.countTypeDto.filterValue) {
    if (Array.isArray(limit.countTypeDto.filterValue)) {
      limit.countTypeDto.filterValue =
        limit.countTypeDto?.filterValue.join(',');
    }
  } else {
    limit.children?.map((item: any) => {
      businessLimitValue(item);
    });
  }
};

// 保存并上线---保存
Bus.on('saveDerive', (n: number) => {
  let successTip = n ? '保存并上线成功' : '保存成功';
  //let failTip = n ? '保存并上线失败' : '保存失败';
  if (route.query.id) {
    // 编辑态
    handleSaveMetrics('editSave', n, successTip);
  } else {
    // 新建
    handleSaveMetrics('buildSave', n, successTip);
  }
});

/**
 * @description 保存、保存并上线
 * @type  类型；保存还是保存并上线
 * @status 0:草稿；1：上线；2：下线
 * @successTip 成功提示
 */
const handleSaveMetrics = async (
  type: string,
  status: any,
  successTip: string
) => {
  //必须要填一个
  if (!state.isStatPeriodSelect && !state.isBusinessLineSelect) {
    Message.warning('请添加统计周期或者业务范围');
    return false;
  }
  formParams.status = status;
  commonParams(0);

  if (type == 'editSave') {
    try {
      const { code } = await API.metricsModelRelation.postUpdateDeriveModel(
        deriveModel.value
      );
      if (code === 200) {
        router.go(-1);
        Message.success(successTip);
      }
    } catch (error) {}
  } else {
    try {
      const { code } = await API.metricsModelRelation.postSaveDeriveModel(
        deriveModel.value
      );
      if (code === 200) {
        router.go(-1);
        Message.success(successTip);
      }
    } catch (error) {}
  }
};

//详情展示
const getDetailData = (obj: any) => {
  if (JSON.stringify(obj) != '{}') {
    deriveModel.value = obj;
  }

  //统计周期
  if (deriveModel.value.countCycleDto) {
    countCycle.value = _.cloneDeep(deriveModel.value.countCycleDto);
    state.isStatPeriodSelect = true;
  }
  if (deriveModel.value.status) {
    formParams.status = deriveModel.value.status;
  }
  if (deriveModel.value.pageNum) {
    formParams.pageNum = deriveModel.value.pageNum;
  }
  if (deriveModel.value.pageSize) {
    formParams.pageSize = deriveModel.value.pageSize;
  }
  if (props.deriveDetailData.modelId) {
    state.modelValue = props.deriveDetailData.modelId;
    state.curModel = state.modelOptions.find(
      (item) => item.id == state.modelValue
    );
  }
  //业务范围处理
  if (
    deriveModel.value.limitDto &&
    JSON.stringify(deriveModel.value.limitDto) != '{}'
  ) {
    let bs = _.cloneDeep(deriveModel.value.limitDto);
    detailBusinessLimitValue(bs, true);
    businessLimit.value = bs;
    state.isBusinessLineSelect = true;
  }

  if (deriveModel.value.dimList) {
    state.dimensionIdList = deriveModel.value.dimList;
  }
};
//详情业务范围数据处理
const detailBusinessLimitValue = (limit: any, isRoot: boolean) => {
  limit.isRoot = isRoot;
  if (!limit.isRoot && limit.children && limit.children.length > 0) {
    limit.compontType = 1;
  } else {
    limit.compontType = 2;
  }

  if (limit.countTypeDto && limit.countTypeDto.filterValue) {
    if (limit.countTypeDto.filterValue) {
      limit.countTypeDto.filterValue =
        limit.countTypeDto?.filterValue.split(',');
    }
  } else {
    limit.children?.map((item: any) => {
      detailBusinessLimitValue(item, false);
    });
  }
};

//保证下拉框有值
watch(
  () => [props.deriveDetailData, state.modelOptions.length],
  (val) => {
    if (val[0] && val[1]) {
      getDetailData(val[0]);
    }
  }
);

onMounted(() => {
  //派生指标id
  let id: any = route.query.metricsId;
  getModelList(id);
});
</script>
<template>
  <div class="deriver-content">
    <div class="develop-type">
      <span class="label">开发方式：</span>
      <a-tabs v-model="state.developType" :disabled="status == 1">
        <a-tab-pane key="1" title="配置"></a-tab-pane>
        <a-tab-pane key="2" title="SQL"></a-tab-pane>
        <a-tab-pane key="3" title="公式"></a-tab-pane>
      </a-tabs>
    </div>
    <div
      class="condision"
      :style="{
        height:
          state.resizeHeight > 0
            ? `calc(100vh - 102px - ${state.resizeHeight}px)`
            : state.resizeHeight == null
            ? `calc(100vh - 102px - 50%)`
            : ''
      }"
    >
      <div class="item-li model">
        <span class="title">数据模型：</span>
        <a-select
          class="data-model-select"
          v-model="state.modelValue"
          :style="{ width: '320px' }"
          :options="state.modelOptions"
          @change="modelChange"
          placeholder="请选择"
          size="large"
          :disabled="status == 1"
          unmountOnClose
        >
          <div class="alert-tips">
            <icon-info-circle />
            <div class="text">
              <span>只可切换至原子指标对应的指标模型;</span>
              <span>切换模型将清空当前所有配置;</span>
            </div>
          </div>
          <template #arrow-icon>
            <icon-caret-down />
          </template>
          <template #label="{ data }">
            <span>{{ data?.label }}</span>
            <span class="extra-tips" v-if="data?.updateType == 1">(全量)</span>
            <span class="extra-tips" v-if="data?.updateType == 2">(增量)</span>
            <span class="extra-tips" v-if="data?.updateType == 3">(拉链)</span>
          </template>
        </a-select>
      </div>
      <div class="item-li">
        <span class="title">指标定义：</span>
      </div>
      <div class="item-li">
        <span class="label">原子指标：</span>
        <div class="index-name">{{ indexCnName }}</div>
      </div>
      <div class="item-li time">
        <span class="label">统计周期：</span>
        <StatPeriod
          v-model:isStatPeriodSelect="state.isStatPeriodSelect"
          :countDateType="state.curModel.countDateType"
          :deriveModel="deriveModel"
          :countCycle="countCycle"
        ></StatPeriod>
      </div>
      <div class="item-li business">
        <span class="label">业务范围：</span>
        <BusinessLine
          :businessLimit="businessLimit"
          :modelTableColumnList="state.modelTableColumnList"
          v-model:isBusinessLineSelect="state.isBusinessLineSelect"
          :treeMax="treeMax"
        ></BusinessLine>
      </div>
      <div class="item-li">
        <span class="title">时间频度：</span>
        <div class="index-time" v-if="deriveModel.timeframe == 'hour'">时</div>
        <div class="index-time" v-if="deriveModel.timeframe == 'day'">日</div>
        <div class="index-time" v-if="deriveModel.timeframe == 'week'">周</div>
        <div class="index-time" v-if="deriveModel.timeframe == 'month'">月</div>
        <div class="index-time" v-if="deriveModel.timeframe == 'quarter'">
          季
        </div>
        <div class="index-time" v-if="deriveModel.timeframe == 'year'">年</div>
      </div>
      <div class="item-li dimension">
        <div class="title">可用维度：</div>
        <a-select
          :disabled="status == 1"
          placeholder="请选择"
          v-model="state.dimensionIdList"
          :options="state.dimensionList"
          size="large"
          multiple
        >
          <template #arrow-icon>
            <icon-caret-down />
          </template>
        </a-select>
      </div>
      <div class="item-li">
        <div class="title"></div>
        <a-button type="outline" @click="handlePreviewData(0)"
          >数据预览</a-button
        >
      </div>
    </div>

    <a-resize-box
      :directions="['top']"
      class="initTable"
      v-model:height="state.resizeHeight"
      :style="{ height: !isShowPreview ? 0 : '50%' }"
    >
      <template #resize-trigger>
        <div class="resizebox-demo resizebox-demo-horizontal">
          <div class="resizebox-demo-line" />
        </div>
      </template>
      <div class="table-result">
        <div class="table-result-title">
          <div class="tabs-name"><span>数据结果</span></div>
          <div :style="{ cursor: 'pointer' }">
            <icon-caret-down
              v-if="isShowPreview"
              @click="
                () => {
                  isShowPreview = !isShowPreview;
                  state.resizeHeight = 0;
                }
              "
            />
            <icon-caret-up
              v-if="!isShowPreview"
              @click="
                () => {
                  isShowPreview = !isShowPreview;
                  state.resizeHeight = null;
                }
              "
            />
          </div>
        </div>
        <div class="table-result-data" v-show="isShowPreview">
          <model-data-result
            ref="defaultTabsRef"
            :preview-data="previewData"
            :index-view-data="indexViewData"
            @changePageNum="changePageNum"
            @changePageSize="changePageSize"
            @changeTableTab="changeTableTab"
          >
          </model-data-result>
        </div>
      </div>
    </a-resize-box>
  </div>
</template>
<style lang="scss" scoped>
@import './index.scss';
</style>